package com.zf.yichat.config.utils;

import com.alibaba.excel.EasyExcel;
import com.itextpdf.text.Document;
import com.itextpdf.text.PageSize;
import com.itextpdf.text.pdf.PdfWriter;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.poi.xwpf.usermodel.XWPFDocument;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class ExportUtil {

    /**
     * 导出 Excel 文件
     *
     * @param dataList 数据列表
     * @param response 文件路径
     */
    public static void exportExcel (List<List<Object>> dataList,String filePath, HttpServletResponse response) throws Exception {
        Workbook workbook = new XSSFWorkbook();
        Sheet sheet = workbook.createSheet ("Sheet1");

        // 设置单元格宽度
        int columnCount = dataList.get (0).size ();
        for (int i = 0; i < columnCount; i++) {
            sheet.setColumnWidth (i, 18 * 256); // 每个单元格的宽度为 20 个字符宽度
        }

        for (int i = 0; i < dataList.size (); i++) {
            List<Object> rowData = dataList.get (i);
            Row row = sheet.createRow (i);

            for (int j = 0; j < rowData.size (); j++) {
                Object cellData = rowData.get (j);
                Cell cell = row.createCell (j);

                if (cellData instanceof Number) {
                    cell.setCellValue (((Number) cellData).doubleValue ());
                } else if (cellData instanceof Boolean) {
                    cell.setCellValue ((Boolean) cellData);
                } else {
                    cell.setCellValue (cellData.toString ());
                }
            }
        }



//        BufferedOutputStream fos = new BufferedOutputStream(response.getOutputStream());
//        workbook.write(fos);
//
//        if (fos != null) {
//            try {
//                fos.close();
//                } catch (IOException e) {
//               }
//            }
        FileOutputStream fos = new FileOutputStream (filePath);
        workbook.write(fos);

        fos.close ();
        workbook.close();
//         在线下载
        download(filePath, response);

    }

    public static void downloadExcel (String filePath, HttpServletResponse response) throws IOException {
        File file = new File (filePath);
        String fileName = file.getName ();

        response.setContentType("application/x-msdownload");
        response.setCharacterEncoding("UTF-8");
        response.setHeader("Content-Disposition", "attachment;fileName=" + URLEncoder.encode(fileName, "UTF-8") + ".xlsx");

        // 启用缓冲区
        response.setBufferSize (4096);

        try (InputStream inputStream = new BufferedInputStream (new FileInputStream (file));
             OutputStream outputStream = new BufferedOutputStream (response.getOutputStream ())) {
            int byteRead;
            while ((byteRead = inputStream.read ()) != -1) {
                outputStream.write (byteRead);
            }
            outputStream.flush (); // 刷新缓冲区，确保所有数据都被写入
        } catch (IOException e) {
            // 处理异常或错误
            throw e;
        } finally {
            // 关闭响应输出流
            if (response != null && response.getOutputStream () != null) {
                response.getOutputStream ().close ();
            }
        }
    }

    //无填充方式导出并下载xlsx
    public static void downloadUnfilledToXlsx(String excelName, HttpServletResponse response, Class cla, List list) throws IOException {
        // 这里注意 使用swagger 会导致各种问题，easyexcel官方文档推荐直接用浏览器或者用postman测试
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("utf-8");
        // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
        String fileName = URLEncoder.encode(excelName, "UTF-8").replaceAll("\\+", "%20");
        response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
        EasyExcel.write(response.getOutputStream(), cla).sheet(excelName).doWrite(list);
    }


    public static void download(String path, HttpServletResponse response) {
        try {
            //下载的文件的路径。
            File file = new File(path);
            String filename = file.getName();
            InputStream fis = new BufferedInputStream(new FileInputStream(path));
            byte[] buffer = new byte[fis.available()];
            fis.read(buffer);
            fis.close();
            // 设置response的Header
            response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(filename, "UTF-8"));
            response.addHeader("Content-Length", "" + file.length());
            response.setContentType("application/vnd.ms-excel");
            response.setCharacterEncoding("utf-8");
            OutputStream os = new BufferedOutputStream(response.getOutputStream());
            os.write(buffer);
            os.flush();
            os.close();
        } catch (IOException ex) {
            throw new RuntimeException("下载文件失败");
        }
    }

    /**
     * 导出 Word 文件
     *
     * @param dataList 数据列表
     * @param filePath 文件路径
     */
    public static void exportWord (List<List<Object>> dataList, String filePath) throws Exception {
        XWPFDocument document = new XWPFDocument ();

        for (List<Object> rowData : dataList) {
            StringBuilder sb = new StringBuilder ();

            for (Object cellData : rowData) {
                sb.append (cellData.toString ()).append ("\t");
            }

            document.createParagraph ().createRun ().setText (sb.toString ());
        }

        FileOutputStream fos = new FileOutputStream (filePath);
        document.write (fos);
        fos.close ();
    }

    /**
     * 导出 PDF 文件
     *
     * @param dataList 数据列表
     * @param filePath 文件路径
     */
    public static void exportPdf (List<List<Object>> dataList, String filePath) throws Exception {
        Document document = new Document(PageSize.A4);

        PdfWriter.getInstance(document, new FileOutputStream (filePath));
        document.open();

        for (List<Object> rowData : dataList) {
            StringBuilder sb = new StringBuilder ();

            for (Object cellData : rowData) {
                sb.append (cellData.toString ()).append ("\t");
            }

            document.add (new com.itextpdf.text.Paragraph (sb.toString ()));
        }

        document.close ();
    }

    public static void main(String[] args) throws Exception {
        // 模拟数据
        List<List<Object>> dataList = new ArrayList<>();
        dataList.add (Arrays.asList ("姓名", "年龄", "性别"));
        dataList.add (Arrays.asList ("", 20, true));
        dataList.add (Arrays.asList ("李四", 25, false));

        // 导出 Excel 文件
//        ExportUtil.exportExcel (dataList, "E:\\data.xlsx");

        // 导出 Word 文件
//        ExportUtil.exportWord (dataList, "E:\\data.docx");

        // 导出 PDF 文件
//        ExportUtil.exportPdf (dataList, "E:\\data.pdf");
    }
}
